/*
 * SPDX-License-Identifier: Apache-2.0
 * Copyright Red Hat Inc. and Hibernate Authors
 */
package org.hibernate.orm.test.mapping.hhh18829;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.lang.reflect.InvocationTargetException;

import static org.junit.jupiter.api.Assertions.assertEquals;

@DomainModel(annotatedClasses = {EmployeeWithoutIdClass.class, AutoGeneratedIdClassTest.Inner.class})
@JiraKey(" HHH-18829")
@SessionFactory
public class AutoGeneratedIdClassTest {

	@BeforeAll
	void setUp(SessionFactoryScope sessionFactoryScope) {
		sessionFactoryScope.inTransaction( sess -> {
			final var one = new EmployeeWithoutIdClass();
			one.empName = "John Doe";
			one.empId = 1;
			one.address = "10 Downing Street, SW1A 2AA";
			sess.persist( one );

			final var two = new EmployeeWithoutIdClass();
			two.empName = "Dave Default";
			two.empId = 1;
			two.address = "1600 Pennsylvania Avenue";
			sess.persist( two );
		} );
		sessionFactoryScope.inTransaction( sess -> {
			final var one = new Inner();
			one.empName = "John Doe";
			one.empId = 1;
			one.address = "10 Downing Street, SW1A 2AA";
			sess.persist( one );

			final var two = new Inner();
			two.empName = "Dave Default";
			two.empId = 13;
			two.address = "1600 Pennsylvania Avenue";
			sess.persist( two );
		} );
	}

	@Test
	public void test(SessionFactoryScope sessionFactoryScope)
			throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {
		final var idClass = Class.forName( EmployeeWithoutIdClass.class.getName() + "_$Id" );
		final var id = idClass.getConstructors()[0].newInstance( "John Doe", 1 );
		final var employees = sessionFactoryScope.fromSession(
				sess -> sess.createQuery( "from EmployeeWithoutIdClass where id=:id", EmployeeWithoutIdClass.class )
						.setParameter( "id", id )
						.getResultList()
		);
		assertEquals( 1, employees.size() );
		assertEquals( "10 Downing Street, SW1A 2AA", employees.get( 0 ).address );
	}

	@Test
	public void innerEntityClassTest(SessionFactoryScope sessionFactoryScope)
			throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {
		final var idClass = Class.forName( AutoGeneratedIdClassTest .class.getName() + "_$Inner_$Id" );
		final var id = idClass.getConstructors()[0].newInstance( "Dave Default", 13 );
		final Inner employee = sessionFactoryScope.fromSession(
				sess -> sess.find( Inner.class, id ) );
		assertEquals( "1600 Pennsylvania Avenue", employee.address );
	}

	@Entity
	static class Inner {
		@Id
		String empName;
		@Id
		Integer empId;
		String address;
	}
}
